home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS / antlr / bits.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-14  |  18.7 KB  |  757 lines  |  [TEXT/MPS ]

  1. /*
  2.  * bits.c -- manage creation and output of bit sets used by the parser.
  3.  *
  4.  * $Id: bits.c,v 1.9 1994/08/29 20:16:14 parrt Exp parrt $
  5.  * $Revision: 1.9 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.23
  28.  * Terence Parr
  29.  * Parr Research Corporation
  30.  * with Purdue University and AHPCRC, University of Minnesota
  31.  * 1989-1994
  32.  */
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "set.h"
  41. #include "syn.h"
  42. #include "hash.h"
  43. #include "generic.h"
  44. #include "dlgdef.h"
  45.  
  46. /* char is only thing that is pretty much always known == 8 bits
  47.  * This allows output of antlr (set stuff, anyway) to be androgynous (portable)
  48.  */
  49. typedef unsigned char SetWordType;
  50. #define BitsPerByte        8
  51. #define BitsPerWord        BitsPerByte*sizeof(SetWordType)
  52.  
  53. static SetWordType *setwd = NULL;
  54. int setnum = -1;
  55. int wordnum = 0;
  56.  
  57. int esetnum = 0;
  58.  
  59. /* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets,
  60.    to bytes that are most portable size-wise.
  61.    */
  62. void
  63. #ifdef __STDC__
  64. DumpIntAsChars( FILE *f, char *format, unsigned wd )
  65. #else
  66. DumpIntAsChars( f, format, wd )
  67. FILE *f;
  68. char *format;
  69. unsigned wd;
  70. #endif
  71. {
  72.     int i;
  73.     /* uses max of 32 bit unsigned integer for the moment */
  74.     static unsigned long byte_mask[sizeof(unsigned long)] =
  75.                 { 0xFF, 0xFF00, 0xFF0000, 0xFF000000 };
  76. /*                  0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/
  77.  
  78.     /* for each byte in the word */
  79.     for (i=0; i<sizeof(unsigned); i++)
  80.     {
  81.         /* mask out the ith byte and shift down to the first 8 bits */
  82.         fprintf(f, format, (wd&byte_mask[i])>>(i*BitsPerByte));
  83.         if ( i<sizeof(unsigned)-1) fprintf(f, ",");
  84.     }
  85. }
  86.  
  87. /* Create a new setwd (ignoring [Ep] token on end) */
  88. void
  89. #ifdef __STDC__
  90. NewSetWd( void )
  91. #else
  92. NewSetWd( )
  93. #endif
  94. {
  95.     SetWordType *p;
  96.  
  97.     if ( setwd == NULL )
  98.     {
  99.         setwd = (SetWordType *) calloc(TokenNum, sizeof(SetWordType));
  100.         require(setwd!=NULL, "NewSetWd: cannot alloc set wd\n");
  101.     }
  102.     for (p = setwd; p<&(setwd[TokenNum]); p++)  {*p=0;}
  103.     wordnum++;
  104. }
  105.  
  106. void
  107. #ifdef __STDC__
  108. DumpSetWd( void )
  109. #else
  110. DumpSetWd( )
  111. #endif
  112. {
  113.     if ( GenCC ) DumpSetWdForCC();
  114.     else DumpSetWdForC();
  115. }
  116.  
  117. /* Dump the current setwd to ErrFile. 0..MaxTokenVal */
  118. void
  119. #ifdef __STDC__
  120. DumpSetWdForC( void )
  121. #else
  122. DumpSetWdForC( )
  123. #endif
  124. {
  125.     int i,c=1;
  126.  
  127.     if ( setwd==NULL ) return;
  128.     if ( !GenCC ) fprintf(DefFile, "extern SetWordType setwd%d[];\n", wordnum);
  129.     fprintf(ErrFile,
  130.             "SetWordType setwd%d[%d] = {", wordnum, TokenNum-1);
  131.     for (i=0; i<TokenNum-1; i++)
  132.     {
  133.         DAWDLE;
  134.         if ( i!=0 ) fprintf(ErrFile, ",");
  135.         if ( c == 8 ) {fprintf(ErrFile, "\n\t"); c=1;} else c++;
  136.         fprintf(ErrFile, "0x%x", setwd[i]);
  137.     }
  138.     fprintf(ErrFile, "};\n");
  139. }
  140.  
  141. /* Dump the current setwd to Parser.C file. 0..MaxTokenVal;
  142.  * Only used if -CC on.
  143.  */
  144. void
  145. #ifdef __STDC__
  146. DumpSetWdForCC( void )
  147. #else
  148. DumpSetWdForCC( )
  149. #endif
  150. {
  151.     int i,c=1;
  152.  
  153.     if ( setwd==NULL ) return;
  154.     fprintf(Parser_h, "\tstatic SetWordType setwd%d[%d];\n", wordnum, TokenNum-1);
  155.     fprintf(Parser_c,
  156.             "SetWordType %s::setwd%d[%d] = {", CurrentClassName, wordnum,
  157.             TokenNum-1);
  158.     for (i=0; i<TokenNum-1; i++)
  159.     {
  160.         DAWDLE;
  161.         if ( i!=0 ) fprintf(Parser_c, ",");
  162.         if ( c == 8 ) {fprintf(Parser_c, "\n\t"); c=1;} else c++;
  163.         fprintf(Parser_c, "0x%x", setwd[i]);
  164.     }
  165.     fprintf(Parser_c, "};\n");
  166. }
  167.  
  168. /* Make a new set.  Dump old setwd and create new setwd if current setwd is full */
  169. void
  170. #ifdef __STDC__
  171. NewSet( void )
  172. #else
  173. NewSet( )
  174. #endif
  175. {
  176.     setnum++;
  177.     if ( setnum==BitsPerWord )        /* is current setwd full? */
  178.     {
  179.         DumpSetWd(); NewSetWd(); setnum = 0;
  180.     }
  181. }
  182.  
  183. /* s is a set of tokens.  Turn on bit at each token position in set 'setnum' */
  184. void
  185. #ifdef __STDC__
  186. FillSet( set s )
  187. #else
  188. FillSet( s )
  189. set s;
  190. #endif
  191. {
  192.     SetWordType mask=(((unsigned)1)<<setnum);
  193.     unsigned int e;
  194.  
  195.     while ( !set_nil(s) )
  196.     {
  197.         e = set_int(s);
  198.         set_rm(e, s);
  199.         setwd[e] |= mask;
  200.     }
  201. }
  202.  
  203.                     /* E r r o r  C l a s s  S t u f f */
  204.  
  205. /* compute the FIRST of a rule for the error class stuff */
  206. static set
  207. #ifdef __STDC__
  208. Efirst( char *rule, ECnode *eclass )
  209. #else
  210. Efirst( rule, eclass )
  211. char *rule;
  212. ECnode *eclass;
  213. #endif
  214. {
  215.     set rk, a;
  216.     Junction *r;
  217.     RuleEntry *q = (RuleEntry *) hash_get(Rname, rule);
  218.  
  219.     if ( q == NULL )
  220.     {
  221.         warnNoFL(eMsg2("undefined rule '%s' referenced in errclass '%s'; ignored",
  222.                         rule, TokenString(eclass->tok)));
  223.         return empty;
  224.     }
  225.     r = RulePtr[q->rulenum];
  226.     r->end->halt = TRUE;        /* don't let reach fall off end of rule here */
  227.     rk = empty;
  228.     REACH(r, 1, &rk, a);
  229.     r->end->halt = FALSE;
  230.     return a;
  231. }
  232.  
  233. /*
  234.  * scan the list of tokens/eclasses/nonterminals filling the new eclass
  235.  * with the set described by the list.  Note that an eclass can be
  236.  * quoted to allow spaces etc... However, an eclass must not conflict
  237.  * with a reg expr found elsewhere.  The reg expr will be taken over
  238.  * the eclass name.
  239.  */
  240. static void
  241. #ifdef __STDC__
  242. doEclass( char *eclass )
  243. #else
  244. doEclass( eclass )
  245. char *eclass;
  246. #endif
  247. {
  248.     TermEntry *q;
  249.     ECnode *p;
  250.     ListNode *e;
  251.     unsigned int t;
  252.     unsigned deg=0;
  253.     set a;
  254.     require(eclass!=NULL, "doEclass: NULL eset");
  255.     
  256.     p = (ECnode *) eclass;
  257.     lexmode(p->lexclass);    /* switch to lexclass where errclass is defined */
  258.     p->eset = empty;
  259.     for (e = (p->elist)->next; e!=NULL; e=e->next)
  260.     {
  261.         if ( islower( *((char *)e->elem) ) )    /* is it a rule ref? (alias FIRST request) */
  262.         {
  263.             a = Efirst((char *)e->elem, p);
  264.             set_orin(&p->eset, a);
  265.             deg += set_deg(a);
  266.             set_free( a );
  267.             continue;
  268.         }
  269.         else if ( *((char *)e->elem)=='"' )
  270.         {
  271.             t = 0;
  272.             q = (TermEntry *) hash_get(Texpr, (char *) e->elem);
  273.             if ( q == NULL )
  274.             {
  275.                 /* if quoted and not an expr look for eclass name */
  276.                 q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem));
  277.                 if ( q != NULL ) t = q->token;
  278.             }
  279.             else t = q->token;
  280.         }
  281.         else    /* labelled token/eclass/tokclass */
  282.         {
  283.             q = (TermEntry *) hash_get(Tname, (char *)e->elem);
  284.             if ( q != NULL )
  285.             {
  286.                 if ( strcmp((char *)e->elem, TokenString(p->tok))==0 )
  287.                 {
  288.                     warnNoFL(eMsg1("self-referential error class '%s'; ignored",
  289.                                    (char *)e->elem));
  290.                     continue;
  291.                 }
  292.                 else
  293.                     t = q->token;
  294.             }
  295.             else t=0;
  296.         }
  297.         if ( t!=0 )
  298.         {
  299.             set_orel(t, &p->eset);
  300.             deg++;
  301.         }
  302.         else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored",
  303.                             (char *)e->elem, TokenString(p->tok)));
  304.     }
  305.     p->setdeg = deg;
  306. }
  307.  
  308. void
  309. #ifdef __STDC__
  310. ComputeErrorSets( void )
  311. #else
  312. ComputeErrorSets( )
  313. #endif
  314. {
  315. #ifdef __cplusplus
  316.     list_apply(eclasses, (void (*)(void *)) doEclass);
  317. #else
  318. #ifdef __STDC__
  319.     list_apply(eclasses, (void (*)(void *)) doEclass);
  320. #else
  321.     list_apply(eclasses, doEclass);
  322. #endif
  323. #endif
  324. }
  325.  
  326. void
  327. #ifdef __STDC__
  328. ComputeTokSets( void )
  329. #else
  330. ComputeTokSets( )
  331. #endif
  332. {
  333.     ListNode *t, *e = NULL;
  334.     int something_changed;
  335.     TCnode *p;
  336.     TermEntry *q;
  337.  
  338.     if ( tclasses == NULL ) return;
  339.  
  340.     /* turn lists of token/tokclass references into sets */
  341.     for (t = tclasses->next; t!=NULL; t=t->next)
  342.     {
  343.         p = (TCnode *) t->elem;
  344.         lexmode(p->lexclass);    /* switch to lexclass where tokclass is defined */
  345.         p->tset = empty;
  346.  
  347.         /* instantiate all tokens/token_classes into the tset */
  348.         for (e = (p->tlist)->next; e!=NULL; e=e->next)
  349.         {
  350.             char *tokstr;
  351.             tokstr = (char *)e->elem;
  352.             if ( *tokstr == '"' ) q = (TermEntry *) hash_get(Texpr, tokstr);
  353.             else q = (TermEntry *) hash_get(Tname, tokstr);
  354.             require(q!=NULL, "ComputeTokSets: no token def");
  355.             set_orel(q->token, &p->tset);
  356.         }
  357.     }
  358.  
  359.     /* Go thru list of tokclasses again looking for tokclasses in sets */
  360. again:
  361.     something_changed = 0;
  362.     for (t = tclasses->next; t!=NULL; t=t->next)
  363.     {
  364.         set tcl;
  365.         p = (TCnode *) t->elem;
  366.         tcl = set_and(p->tset, imag_tokens);
  367.         if ( !set_nil(tcl) )
  368.         {
  369.             int tk;
  370.             /* replace refs to tokclasses with the associated set of tokens */
  371.             something_changed = 1;
  372.             while ( !set_nil(tcl) )
  373.             {
  374.                 tk = set_int(tcl);        /* grab one of the tok class refs */
  375.                 set_rm(tk, tcl);
  376.                 if ( p->tok != tk )        /* tokclass ref to yourself? */
  377.                 {
  378.                     q = (TermEntry *) hash_get(Tname, TokenString(tk));
  379.                     require(q!=NULL, "#tokclass not in hash table");
  380.                     set_orin(&p->tset, q->tclass->tset);
  381.                 }
  382.                 set_rm(tk, p->tset);    /* remove ref that we replaced */
  383.             }
  384.         }
  385.         set_free(tcl);
  386.     }
  387.     if ( something_changed ) goto again;
  388. }
  389.  
  390. /* replace a subset of an error set with an error class name if a subset is found
  391.  * repeat process until no replacements made
  392.  */
  393. void
  394. #ifdef __STDC__
  395. SubstErrorClass( set *f )
  396. #else
  397. SubstErrorClass( f )
  398. set *f;
  399. #endif
  400. {
  401.     int max, done = 0;
  402.     ListNode *p;
  403.     ECnode *ec, *maxclass = NULL;
  404.     set a;
  405.     require(f!=NULL, "SubstErrorClass: NULL eset");
  406.  
  407.     if ( eclasses == NULL ) return;
  408.     while ( !done )
  409.     {
  410.         max = 0;
  411.         maxclass = NULL;
  412.         for (p=eclasses->next; p!=NULL; p=p->next)    /* chk all error classes */
  413.         {
  414.             ec = (ECnode *) p->elem;
  415.             if ( ec->setdeg > max )
  416.             {
  417.                 if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) )
  418.                     {maxclass = ec; max=ec->setdeg;}
  419.             }
  420.         }
  421.         if ( maxclass != NULL )    /* if subset found, replace with token */
  422.         {
  423.             a = set_dif(*f, maxclass->eset);
  424.             set_orel((unsigned)maxclass->tok, &a);
  425.             set_free(*f);
  426.             *f = a;
  427.         }
  428.         else done = 1;
  429.     }
  430. }
  431.  
  432. int
  433. #ifdef __STDC__
  434. DefErrSet( set *f, int subst )
  435. #else
  436. DefErrSet( f, subst )
  437. set *f;
  438. int subst;            /* should be substitute error classes? */
  439. #endif
  440. {
  441.     if ( GenCC ) return DefErrSetForCC( f, subst );
  442.     else return DefErrSetForC( f, subst );
  443. }
  444.  
  445. /* Define a new error set.  WARNING...set-implementation dependent.
  446.  */
  447. int
  448. #ifdef __STDC__
  449. DefErrSetForC( set *f, int subst )
  450. #else
  451. DefErrSetForC( f, subst )
  452. set *f;
  453. int subst;            /* should be substitute error classes? */
  454. #endif
  455. {
  456.     unsigned *p, *endp;
  457.     int e=1;
  458.     require(!set_nil(*f), "DefErrSet: nil set to dump?");
  459.  
  460.     if ( subst ) SubstErrorClass(f);
  461.     p = f->setword;
  462.     endp = &(f->setword[NumWords(TokenNum-1)]);
  463.     esetnum++;
  464.     if ( !GenCC ) fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum);
  465.     fprintf(ErrFile, "SetWordType zzerr%d[%d] = {", esetnum, NumWords(TokenNum-1)*sizeof(unsigned));
  466.     while ( p < endp )
  467.     {
  468.         if ( e > 1 ) fprintf(ErrFile, ", ");
  469.         DumpIntAsChars(ErrFile, "0x%x", *p++);
  470.         if ( e == 3 )
  471.         {
  472.             DAWDLE;
  473.             if ( p < endp ) fprintf(ErrFile, ",");
  474.             fprintf(ErrFile, "\n\t");
  475.             e=1;
  476.         }
  477.         else e++;
  478.     }
  479.     fprintf(ErrFile, "};\n");
  480.  
  481.     return esetnum;
  482. }
  483.  
  484. /* Define a new error set.  WARNING...set-implementation dependent;
  485.  * Only used when -CC on.
  486.  */
  487. int
  488. #ifdef __STDC__
  489. DefErrSetForCC( set *f, int subst )
  490. #else
  491. DefErrSetForCC( f, subst )
  492. set *f;
  493. int subst;            /* should be substitute error classes? */
  494. #endif
  495. {
  496.     unsigned *p, *endp;
  497.     int e=1;
  498.     require(!set_nil(*f), "DefErrSet: nil set to dump?");
  499.  
  500.     if ( subst ) SubstErrorClass(f);
  501.     p = f->setword;
  502.     endp = &(f->setword[NumWords(TokenNum-1)]);
  503.     esetnum++;
  504.     fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum,
  505.             NumWords(TokenNum-1)*sizeof(unsigned));
  506.     fprintf(Parser_c, "SetWordType %s::err%d[%d] = {", CurrentClassName, esetnum, NumWords(TokenNum-1)*sizeof(unsigned));
  507.     while ( p < endp )
  508.     {
  509.         if ( e > 1 ) fprintf(Parser_c, ", ");
  510.         DumpIntAsChars(Parser_c, "0x%x", *p++);
  511.         if ( e == 3 )
  512.         {
  513.             if ( p < endp ) fprintf(Parser_c, ",");
  514.             fprintf(Parser_c, "\n\t");
  515.             e=1;
  516.         }
  517.         else e++;
  518.     }
  519.     fprintf(Parser_c, "};\n");
  520.  
  521.     return esetnum;
  522. }
  523.  
  524. void
  525. #ifdef __STDC__
  526. GenParser_c_Hdr(void)
  527. #else
  528. GenParser_c_Hdr()
  529. #endif
  530. {
  531.     int i,j;
  532.  
  533.     fprintf(Parser_c, "/*\n");
  534.     fprintf(Parser_c, " * %s: P a r s e r  S u p p o r t\n", CurrentClassName);
  535.     fprintf(Parser_c, " *\n");
  536.     fprintf(Parser_c, " * Generated from:");
  537.     for (i=0; i<NumFiles; i++) fprintf(Parser_c, " %s", FileStr[i]);
  538.     fprintf(Parser_c, "\n");
  539.     fprintf(Parser_c, " *\n");
  540.     fprintf(Parser_c, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  541.     fprintf(Parser_c, " * Purdue University Electrical Engineering\n");
  542.     fprintf(Parser_c, " * With AHPCRC, University of Minnesota\n");
  543.     fprintf(Parser_c, " * ANTLR Version %s\n", Version);
  544.     fprintf(Parser_c, " */\n\n");
  545.     fprintf(Parser_c, "#include <stdio.h>\n");
  546.     fprintf(Parser_c, "#define ANTLR_VERSION    %s\n", VersionDef);
  547.     if ( UserTokenDefsFile != NULL )
  548.        fprintf(Parser_c, "#include %s\n", UserTokenDefsFile);
  549.     else
  550.        fprintf(Parser_c, "#include \"%s\"\n", DefFileName);
  551.  
  552.     fprintf(Parser_c, "#include \"%s.h\"\n", CurrentClassName);
  553.  
  554.     /* Dump a Parser::tokens for each automaton */
  555.     fprintf(Parser_c, "\nANTLRChar *%s::_token_tbl[]={\n", CurrentClassName);
  556.     fprintf(Parser_c, "\t/* 00 */\t\"Invalid\"");
  557.  
  558.     for (i=1; i<TokenNum-1; i++)
  559.     {
  560.         DAWDLE;
  561.         if ( i == EpToken ) continue;
  562.         /* remapped to invalid token? */
  563.         if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
  564.         {
  565.             fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i);
  566.             continue;
  567.         }
  568.         if ( TokenString(i) != NULL )
  569.             fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
  570.         else
  571.         {
  572.             /* look in all lexclasses for the reg expr */
  573.             for (j=0; j<NumLexClasses; j++)
  574.             {
  575.                 lexmode(j);
  576.                 if ( ExprString(i) != NULL )
  577.                 {
  578.                     fprintf(Parser_c, ",\n\t/* %02d */\t", i);
  579.                     dumpExpr(Parser_c, ExprString(i));
  580.                     break;
  581.                 }
  582.             }
  583.             if ( j>=NumLexClasses )
  584.             {
  585.                 if ( UserDefdTokens )
  586.                 {
  587.                     fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i);
  588.                 }
  589.                 else
  590.                     fatal_internal(eMsgd("No label or expr for token %d",i));
  591.             }
  592.         }
  593.     }
  594.     fprintf(Parser_c, "\n};\n");
  595.  
  596.     /* Build constructors */
  597.     fprintf(Parser_c, "\n%s::", CurrentClassName);
  598.     fprintf(Parser_c,    "%s(ANTLRTokenBuffer *input) : ANTLRParser(input,%d,%d,%d,%d)\n",
  599.                         CurrentClassName,
  600.                         OutputLL_k,
  601.                         FoundGuessBlk,
  602.                         DemandLookahead,
  603.                         NumWords(TokenNum-1)*sizeof(unsigned));
  604.     fprintf(Parser_c, "{\n");
  605.     fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n");
  606.     fprintf(Parser_c, "}\n\n");
  607. }
  608.  
  609. void
  610. #ifdef __STDC__
  611. GenParser_h_Hdr(void)
  612. #else
  613. GenParser_h_Hdr()
  614. #endif
  615. {
  616.     int i;
  617.  
  618.     fprintf(Parser_h, "/*\n");
  619.     fprintf(Parser_h, " * %s: P a r s e r  H e a d e r \n", CurrentClassName);
  620.     fprintf(Parser_h, " *\n");
  621.     fprintf(Parser_h, " * Generated from:");
  622.     for (i=0; i<NumFiles; i++) fprintf(Parser_h, " %s", FileStr[i]);
  623.     fprintf(Parser_h, "\n");
  624.     fprintf(Parser_h, " *\n");
  625.     fprintf(Parser_h, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  626.     fprintf(Parser_h, " * Purdue University Electrical Engineering\n");
  627.     fprintf(Parser_h, " * With AHPCRC, University of Minnesota\n");
  628.     fprintf(Parser_h, " * ANTLR Version %s\n", Version);
  629.     fprintf(Parser_h, " */\n\n");
  630.     if ( GenAST ) fprintf(Parser_h, "class ASTBase;\n");
  631.     fprintf(Parser_h, "#include \"%s\"\n\n", APARSER_H);
  632.  
  633.     if ( HdrAction != NULL ) dumpAction( HdrAction, Parser_h, 0, -1, 0, 1);
  634.     
  635.     fprintf(Parser_h, "class %s : public ANTLRParser {\n", CurrentClassName);
  636.     fprintf(Parser_h, "protected:\n");
  637.     fprintf(Parser_h, "\tstatic ANTLRChar *_token_tbl[];\n");
  638.     fprintf(Parser_h, "private:\n");
  639. }
  640.  
  641. /* Currently, this is only used in !GenCC mode */
  642. void
  643. #ifdef __STDC__
  644. GenErrHdr( void )
  645. #else
  646. GenErrHdr( )
  647. #endif
  648. {
  649.     int i, j;
  650.  
  651.     fprintf(ErrFile, "/*\n");
  652.     fprintf(ErrFile, " * A n t l r  S e t s / E r r o r  F i l e  H e a d e r\n");
  653.     fprintf(ErrFile, " *\n");
  654.     fprintf(ErrFile, " * Generated from:");
  655.     for (i=0; i<NumFiles; i++) fprintf(ErrFile, " %s", FileStr[i]);
  656.     fprintf(ErrFile, "\n");
  657.     fprintf(ErrFile, " *\n");
  658.     fprintf(ErrFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  659.     fprintf(ErrFile, " * Purdue University Electrical Engineering\n");
  660.     fprintf(ErrFile, " * With AHPCRC, University of Minnesota\n");
  661.     fprintf(ErrFile, " * ANTLR Version %s\n", Version);
  662.     fprintf(ErrFile, " */\n\n");
  663.     fprintf(ErrFile, "#include <stdio.h>\n");
  664.     fprintf(ErrFile, "#define ANTLR_VERSION    %s\n", VersionDef);
  665.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  666.         fprintf(ErrFile, "#define %s %s\n", DefaultParserName, ParserName);
  667.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  668.         fprintf(ErrFile, "#include \"%s\"\n", RemapFileName);
  669.     if ( HdrAction != NULL ) dumpAction( HdrAction, ErrFile, 0, -1, 0, 1 );
  670.     if ( FoundGuessBlk )
  671.     {
  672.         fprintf(ErrFile, "#define ZZCAN_GUESS\n");
  673.         fprintf(ErrFile, "#include <setjmp.h>\n");
  674.     }
  675.  
  676.     if ( OutputLL_k > 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k);
  677.     if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
  678.     fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));
  679.     if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n");
  680.     fprintf(ErrFile, "#include \"antlr.h\"\n");
  681.     if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n");
  682.             
  683.     if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile);
  684.     /* still need this one as it has the func prototypes */
  685.     fprintf(ErrFile, "#include \"%s\"\n", DefFileName);
  686.     fprintf(ErrFile, "#include \"dlgdef.h\"\n");
  687.     fprintf(ErrFile, "#include \"err.h\"\n\n");
  688.  
  689.     /* Dump a zztokens for each automaton */
  690.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  691.     {
  692.         fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1);
  693.     }
  694.     else
  695.     {
  696.         fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1);
  697.     }
  698.     fprintf(ErrFile, "\t/* 00 */\t\"Invalid\"");
  699.     for (i=1; i<TokenNum-1; i++)
  700.     {
  701.         DAWDLE;
  702.         if ( i == EpToken ) continue;
  703.         /* remapped to invalid token? */
  704.         if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
  705.         {
  706.             fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i);
  707.             continue;
  708.         }
  709.         if ( TokenString(i) != NULL )
  710.             fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
  711.         else
  712.         {
  713.             /* look in all lexclasses for the reg expr */
  714.             for (j=0; j<NumLexClasses; j++)
  715.             {
  716.                 lexmode(j);
  717.                 if ( ExprString(i) != NULL )
  718.                 {
  719.                     fprintf(ErrFile, ",\n\t/* %02d */\t", i);
  720.                     dumpExpr(ErrFile, ExprString(i));
  721.                     break;
  722.                 }
  723.             }
  724.             if ( j>=NumLexClasses )
  725.             {
  726.                 if ( UserDefdTokens )
  727.                 {
  728.                     fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i);
  729.                 }
  730.                 else
  731.                     fatal_internal(eMsgd("No label or expr for token %d",i));
  732.             }
  733.         }
  734.     }
  735.     fprintf(ErrFile, "\n};\n");
  736. }
  737.  
  738. void
  739. #ifdef __STDC__
  740. dumpExpr( FILE *f, char *e )
  741. #else
  742. dumpExpr( f, e )
  743. FILE *f;
  744. char *e;
  745. #endif
  746. {
  747.     while ( *e!='\0' )
  748.     {
  749.         if ( *e=='\\' && *(e+1)=='\\' )
  750.             {putc('\\', f); putc('\\', f); e+=2;}
  751.         else if ( *e=='\\' && *(e+1)=='"' )
  752.             {putc('\\', f); putc('"', f); e+=2;}
  753.         else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;}
  754.         else {putc(*e, f); e++;}
  755.     }
  756. }
  757.